/*
 * Copyright (c) 2025 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import { ClassAnalysis, IGeneratedFile, IGenerationResult, Logger, ITaskContext, GeneratedFileInfo } from '..';
import { CodeAnalysisService } from './CodeAnalysisService';
import { CodeGenerationService } from './CodeGenerationService';
import { SendableMergeabilityRegistry } from '../analyzers/SendableMergeabilityRegistry';
import { SendableMergeChecker } from '../analyzers/SendableMergeChecker';
import { CustomTypeAnalyzer } from '../analyzers/CustomTypeAnalyzer';

export class CodeGenerationEngine {
  private readonly analysisService: CodeAnalysisService
  private readonly generationService: CodeGenerationService

  // 保存分析结果供导入重写使用
  private allClassAnalysis: ClassAnalysis[] = []

  constructor() {
    this.analysisService = new CodeAnalysisService()
    this.generationService = new CodeGenerationService()
  }

  /**
   * @param scanFiles 待处理的源文件路径列表
   * @param context 任务上下文
   * @returns 生成结果详情
   */
  processFilesUnified(scanFiles: string[], context: ITaskContext): IGenerationResult {
    if (!scanFiles || scanFiles.length === 0) {
      Logger.info('没有待处理的源文件')
      return {
        generatedFiles: [],
        skippedFiles: []
      }
    }

    const generatedFiles: IGeneratedFile[] = []
    const skippedFiles: string[] = []

    // 重置分析结果和合并性注册表
    this.allClassAnalysis = []
    SendableMergeabilityRegistry.clear()

    Logger.info(`开始处理 ${scanFiles.length} 个源文件`)

    // ========== 阶段1：分析所有文件并检查合并性 ==========
    Logger.debug(`[阶段1] 开始分析所有文件`)
    const fileAnalysisMap = new Map<string, ClassAnalysis[]>()

    // 步骤1.1：分析所有文件的基本信息
    for (const filePath of scanFiles) {
      const classAnalysis = this.analysisService.analyzeFile(filePath)

      if (classAnalysis.length === 0) {
        skippedFiles.push(filePath)
        Logger.debug(`跳过文件（无@Serializable类）: ${filePath}`)
        continue
      }

      // 保存分析结果
      fileAnalysisMap.set(filePath, classAnalysis)
      this.allClassAnalysis.push(...classAnalysis)
    }

    Logger.debug(`[阶段1.1] 完成基本分析，共 ${this.allClassAnalysis.length} 个类`)

    // 步骤1.2：检查所有类的合并性并注册到全局注册表
    Logger.debug(`[阶段1.2] 开始检查合并性并注册`)
    for (const analysis of this.allClassAnalysis) {
      // 仅对启用 generateSendable 的类检查合并性
      if (analysis.decorators.serializable?.generateSendable) {
        analysis.canMerge = SendableMergeChecker.check(analysis)
        SendableMergeabilityRegistry.register(analysis.className, analysis.canMerge)
      } else {
        // 未启用 generateSendable 的类，注册为不可合并
        SendableMergeabilityRegistry.register(analysis.className, false)
      }
    }

    // ========== 阶段2：生成所有文件 ==========
    Logger.debug(`[阶段2] 开始生成所有文件`)

    for (const [filePath, classAnalysis] of fileAnalysisMap.entries()) {
      const generatedFile = this.generationService.generateForSourceFile(filePath, classAnalysis, context)
      if (generatedFile) {
        generatedFiles.push(generatedFile)
        Logger.debug(`成功处理文件: ${filePath}`)
      } else {
        Logger.warn(`文件生成失败: ${filePath}`)
      }
    }

    Logger.info(`处理完成，成功 ${generatedFiles.length} 个，跳过 ${skippedFiles.length} 个`)

    return { generatedFiles, skippedFiles }
  }

  /**
   * @param filePath 源文件路径
   * @param context 任务上下文
   * @returns 生成的文件信息，如果无需生成则返回null
   */
  processFileUnified(filePath: string, context: ITaskContext): IGeneratedFile | null {
    const classAnalysis = this.analysisService.analyzeFile(filePath)

    // 如果没有@Serializable类，跳过生成
    if (classAnalysis.length === 0) {
      Logger.debug(`源文件 ${filePath} 无@Serializable类，跳过生成`)
      return null
    }

    // 保存分析结果供导入重写使用
    this.allClassAnalysis.push(...classAnalysis)

    // 生成对应文件
    return this.generationService.generateForSourceFile(filePath, classAnalysis, context)
  }


  /**
   * 收集所有生成的文件信息
   * 供导入重写功能使用
   * @param context 任务上下文
   * @returns 生成文件信息列表
   */
  collectGeneratedFileInfos(context: ITaskContext): GeneratedFileInfo[] {
    // 按源文件路径分组收集类名
    const fileInfoMap = new Map<string, GeneratedFileInfo>();

    for (const analysisResult of this.allClassAnalysis) {
      const sourceFilePath = analysisResult.sourceFilePath;

      if (!fileInfoMap.has(sourceFilePath)) {
        // 为新文件创建 GeneratedFileInfo
        const generatedFilePath = context.mapToOutputPath(sourceFilePath);
        fileInfoMap.set(sourceFilePath, {
          sourceFilePath,
          generatedFilePath,
          classNames: new Set<string>()
        });
      }

      // 添加类名到对应文件的集合中
      const fileInfo = fileInfoMap.get(sourceFilePath)!;
      fileInfo.classNames.add(analysisResult.className);
    }

    return Array.from(fileInfoMap.values());
  }

  /**
   * 获取所有分析结果
   * 供外部使用（如调试）
   */
  getAllAnalysisResults(): ClassAnalysis[] {
    return [...this.allClassAnalysis]
  }

  /**
   * 清理资源
   * 注意：这个方法应该在整个流程（包括导入重写）完成后调用
   */
  cleanup(): void {
    this.analysisService.dispose()
    this.allClassAnalysis = []
    CustomTypeAnalyzer.getInstance().clearCache()
    SendableMergeabilityRegistry.clear()
  }
}
